home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / Pascal / Applications / P4⁄Mac 1.0 / Mac source / pint⁄m.p < prev   
Encoding:
Text File  |  1994-07-29  |  34.0 KB  |  1,738 lines  |  [TEXT/PJMM]

  1. (*Assembler and interpreter of Pascal code*)
  2. (*K. Jensen, N. Wirth, Ch. Jacobi, ETH May 76*)
  3.  
  4. {Mac port by Ingemar Ragnemalm 1994. Look for "{” comments to find my changes.}
  5.  
  6. program pcode (input, output, prd, prr);
  7.  
  8. (* Note for the implementation.}
  9. {   ===========================}
  10. {This interpreter is written for the case where all the fundamental types}
  11. {take one storage unit.}
  12. {In an actual implementation, the handling of the sp pointer has to take}
  13. {into account the fact that the types may have lengths different from one:}
  14. {in push and pop operations the sp has to be increased and decreased not}
  15. {by 1, but by a number depending on the type concerned.}
  16. {However, where the number of units of storage has been computed by the}
  17. {compiler, the value must not be corrected, since the lengths of the types}
  18. {involved have already been taken into account.}
  19. {                                 *)
  20.  
  21.  
  22.     label
  23.         1;
  24.     const
  25.         codemax = 8650;
  26.         pcmax = 17500;
  27.         maxstk = 13650; (* size of variable store *)
  28.         overi = 13655; (* size of integer constant table = 5 *)
  29.         overr = 13660; (* size of real constant table = 5 *)
  30.         overs = 13730; (* size of set constant table = 70 *)
  31.         overb = 13820;
  32.         overm = 18000;
  33.         maxstr = 18001;
  34.         largeint = 26144;
  35.         begincode = 3;
  36.         inputadr = 5;
  37.         outputadr = 6;
  38.         prdadr = 7;
  39.         prradr = 8;
  40.         duminst = 62;
  41.  
  42.     type
  43.         bit4 = 0..15;
  44.         bit6 = 0..127;
  45.         bit20 = -26143..26143;
  46.         datatype = (undef, int, reel, bool, sett, adr, mark, car);
  47.         address = -1..maxstr;
  48.         beta = string[25]; {IR: Was: packed array[1..25] of char; (*error message*)
  49.         settype = set of 0..58;
  50.         alfa = packed array[1..10] of char;
  51.  
  52.         codeType = array[0..codemax] of packed record   (* the program *)
  53.                 op1: bit6;
  54.                 p1: bit4;
  55.                 q1: bit20;
  56.                 op2: bit6;
  57.                 p2: bit4;
  58.                 q2: bit20
  59.             end;
  60.         codePtr = ^codeType;
  61.  
  62.         storeType = array[0..overm] of record
  63.                 case datatype of
  64.                     int: (
  65.                             vi: integer
  66.                     );
  67.                     reel: (
  68.                             vr: real
  69.                     );
  70.                     bool: (
  71.                             vb: boolean
  72.                     );
  73.                     sett: (
  74.                             vs: settype
  75.                     );
  76.                     car: (
  77.                             vc: char
  78.                     );
  79.                     adr: (
  80.                             va: address
  81.                     );
  82.                          (*address in store*)
  83.                     mark: (
  84.                             vm: integer
  85.                     )
  86.             end;
  87.         storePtr = ^storeType;
  88.  
  89.     var
  90.         code: codePtr;
  91.  
  92.         pc: 0..pcmax;     (*program address register*)
  93.         op: bit6;
  94.         p: bit4;
  95.         q: bit20;  (*instruction register*)
  96.  
  97.         store: storePtr;
  98.  
  99.         mp, sp, np, ep: address;  (* address registers *)
  100.        (*mp  points to beginning of a data segment}
  101. {     sp  points to top of the stack}
  102. {     ep  points to the maximum extent of the stack}
  103. {     np  points to top of the dynamically allocated area*)
  104.  
  105.         interpreting: boolean;
  106.         prd, prr: text;(*prd for read only, prr for write only *)
  107.  
  108.         instr: array[bit6] of alfa; (* mnemonic instruction codes *)
  109.         cop: array[bit6] of integer;
  110.         sptable: array[0..20] of alfa; (*standard functions and procedures*)
  111.  
  112.       (*locally used for interpreting one instruction*)
  113.         ad, ad1: address;
  114.         b: boolean;
  115.         i, j, i1, i2: integer;
  116.         c: char;
  117.  
  118. (*--------------------------------------------------------------------*)
  119.  
  120.     procedure load;
  121.         const
  122.             maxlabel = 1850;
  123.         type
  124.             labelst = (entered, defined); (*label situation*)
  125.             labelrg = 0..maxlabel;       (*label range*)
  126.             labelrec = record
  127.                     val: address;
  128.                     st: labelst
  129.                 end;
  130.         var
  131.             icp, rcp, scp, bcp, mcp: address;  (*pointers to next free position*)
  132.             word: array[1..10] of char;
  133.             i: integer;
  134.             ch: char;
  135.             labeltab: array[labelrg] of labelrec;
  136.             labelvalue: address;
  137.  
  138.         procedure init;
  139.             var
  140.                 i: integer;
  141.         begin
  142.             instr[0] := 'lod       ';
  143.             instr[1] := 'ldo       ';
  144.             instr[2] := 'str       ';
  145.             instr[3] := 'sro       ';
  146.             instr[4] := 'lda       ';
  147.             instr[5] := 'lao       ';
  148.             instr[6] := 'sto       ';
  149.             instr[7] := 'ldc       ';
  150.             instr[8] := '...       ';
  151.             instr[9] := 'ind       ';
  152.             instr[10] := 'inc       ';
  153.             instr[11] := 'mst       ';
  154.             instr[12] := 'cup       ';
  155.             instr[13] := 'ent       ';
  156.             instr[14] := 'ret       ';
  157.             instr[15] := 'csp       ';
  158.             instr[16] := 'ixa       ';
  159.             instr[17] := 'equ       ';
  160.             instr[18] := 'neq       ';
  161.             instr[19] := 'geq       ';
  162.             instr[20] := 'grt       ';
  163.             instr[21] := 'leq       ';
  164.             instr[22] := 'les       ';
  165.             instr[23] := 'ujp       ';
  166.             instr[24] := 'fjp       ';
  167.             instr[25] := 'xjp       ';
  168.             instr[26] := 'chk       ';
  169.             instr[27] := 'eof       ';
  170.             instr[28] := 'adi       ';
  171.             instr[29] := 'adr       ';
  172.             instr[30] := 'sbi       ';
  173.             instr[31] := 'sbr       ';
  174.             instr[32] := 'sgs       ';
  175.             instr[33] := 'flt       ';
  176.             instr[34] := 'flo       ';
  177.             instr[35] := 'trc       ';
  178.             instr[36] := 'ngi       ';
  179.             instr[37] := 'ngr       ';
  180.             instr[38] := 'sqi       ';
  181.             instr[39] := 'sqr       ';
  182.             instr[40] := 'abi       ';
  183.             instr[41] := 'abr       ';
  184.             instr[42] := 'not       ';
  185.             instr[43] := 'and       ';
  186.             instr[44] := 'ior       ';
  187.             instr[45] := 'dif       ';
  188.             instr[46] := 'int       ';
  189.             instr[47] := 'uni       ';
  190.             instr[48] := 'inn       ';
  191.             instr[49] := 'mod       ';
  192.             instr[50] := 'odd       ';
  193.             instr[51] := 'mpi       ';
  194.             instr[52] := 'mpr       ';
  195.             instr[53] := 'dvi       ';
  196.             instr[54] := 'dvr       ';
  197.             instr[55] := 'mov       ';
  198.             instr[56] := 'lca       ';
  199.             instr[57] := 'dec       ';
  200.             instr[58] := 'stp       ';
  201.             instr[59] := 'ord       ';
  202.             instr[60] := 'chr       ';
  203.             instr[61] := 'ujc       ';
  204.  
  205.             sptable[0] := 'get       ';
  206.             sptable[1] := 'put       ';
  207.             sptable[2] := 'rst       ';
  208.             sptable[3] := 'rln       ';
  209.             sptable[4] := 'new       ';
  210.             sptable[5] := 'wln       ';
  211.             sptable[6] := 'wrs       ';
  212.             sptable[7] := 'eln       ';
  213.             sptable[8] := 'wri       ';
  214.             sptable[9] := 'wrr       ';
  215.             sptable[10] := 'wrc       ';
  216.             sptable[11] := 'rdi       ';
  217.             sptable[12] := 'rdr       ';
  218.             sptable[13] := 'rdc       ';
  219.             sptable[14] := 'sin       ';
  220.             sptable[15] := 'cos       ';
  221.             sptable[16] := 'exp       ';
  222.             sptable[17] := 'log       ';
  223.             sptable[18] := 'sqt       ';
  224.             sptable[19] := 'atn       ';
  225.             sptable[20] := 'sav       ';
  226.  
  227.             cop[0] := 105;
  228.             cop[1] := 65;
  229.             cop[2] := 70;
  230.             cop[3] := 75;
  231.             cop[6] := 80;
  232.             cop[9] := 85;
  233.             cop[10] := 90;
  234.             cop[26] := 95;
  235.             cop[57] := 100;
  236.  
  237.             pc := begincode;
  238.             icp := maxstk + 1;
  239.             rcp := overi + 1;
  240.             scp := overr + 1;
  241.             bcp := overs + 2;
  242.             mcp := overb + 1;
  243.             for i := 1 to 10 do
  244.                 word[i] := ' ';
  245.             for i := 0 to maxlabel do
  246.                 with labeltab[i] do
  247.                     begin
  248.                         val := -1;
  249.                         st := entered
  250.                     end;
  251.             reset(prd);
  252.         end;(*init*)
  253.  
  254.         procedure errorl (theString: beta); (*error in loading*)
  255.         begin
  256.             writeln;
  257.             write(theString);
  258.             halt
  259.         end; (*errorl*)
  260.  
  261.         procedure update (x: labelrg); (*when a label definition lx is found*)
  262.             var
  263.                 curr, succ: -1..pcmax;  (*resp. current element and successor element}
  264. {                   of a list of future references*)
  265.                 endlist: boolean;
  266.         begin
  267.             if labeltab[x].st = defined then
  268.                 errorl(' duplicated label           ')
  269.             else
  270.                 begin
  271.                     if labeltab[x].val <> -1 then (*forward reference(s)*)
  272.                         begin
  273.                             curr := labeltab[x].val;
  274.                             endlist := false;
  275.                             while not endlist do
  276.                                 with code^[curr div 2] do
  277.                                     begin
  278.                                         if odd(curr) then
  279.                                             begin
  280.                                                 succ := q2;
  281.                                                 q2 := labelvalue
  282.                                             end
  283.                                         else
  284.                                             begin
  285.                                                 succ := q1;
  286.                                                 q1 := labelvalue
  287.                                             end;
  288.                                         if succ = -1 then
  289.                                             endlist := true
  290.                                         else
  291.                                             curr := succ
  292.                                     end;
  293.                         end;
  294.                     labeltab[x].st := defined;
  295.                     labeltab[x].val := labelvalue;
  296.                 end
  297.         end;(*update*)
  298.  
  299.         procedure assemble;
  300.         forward;
  301.  
  302.         procedure generate;(*generate segment of code*)
  303.             var
  304.                 x: integer; (* label number *)
  305.                 again: boolean;
  306.         begin
  307.             again := true;
  308.             while again do
  309.                 begin
  310.                     read(prd, ch);(* first character of line*)
  311.                     case ch of
  312.                         'i': 
  313.                             readln(prd);
  314.                         'l': 
  315.                             begin
  316.                                 read(prd, x);
  317.                                 if not eoln(prd) then
  318.                                     read(prd, ch);
  319.                                 if ch = '=' then
  320.                                     read(prd, labelvalue)
  321.                                 else
  322.                                     labelvalue := pc;
  323.                                 update(x);
  324.                                 readln(prd);
  325.                             end;
  326.                         'q': 
  327.                             begin
  328.                                 again := false;
  329.                                 readln(prd)
  330.                             end;
  331.                         ' ': 
  332.                             begin
  333.                                 read(prd, ch);
  334.                                 assemble
  335.                             end
  336.                     end;
  337.                 end
  338.         end; (*generate*)
  339.  
  340.         procedure assemble; (*translate symbolic code into machine code and store*)
  341.             label
  342.                 1;     (*goto 1 for instructions without code generation*)
  343.             var
  344.                 name: alfa;
  345.                 b: boolean;
  346.                 r: real;
  347.                 s: settype;
  348.                 c1: char;
  349.                 i, s1, lb, ub: integer;
  350.  
  351.             procedure lookup (x: labelrg); (* search in label table*)
  352.             begin
  353.                 case labeltab[x].st of
  354.                     entered: 
  355.                         begin
  356.                             q := labeltab[x].val;
  357.                             labeltab[x].val := pc
  358.                         end;
  359.                     defined: 
  360.                         q := labeltab[x].val
  361.                 end(*case label..*)
  362.             end;(*lookup*)
  363.  
  364.             procedure labelsearch;
  365.                 var
  366.                     x: labelrg;
  367.             begin
  368.                 while (ch <> 'l') and not eoln(prd) do
  369.                     read(prd, ch);
  370.                 read(prd, x);
  371.                 lookup(x)
  372.             end;(*labelsearch*)
  373.  
  374.             procedure getname;
  375.                 var
  376.                     i: integer; {fix for pack}
  377.             begin
  378.                 word[1] := ch;
  379.                 read(prd, word[2], word[3]);
  380.                 if not eoln(prd) then
  381.                     read(prd, ch); (*next character*)
  382. {pack(word, 1, name) doesn't exist, replace by:}
  383.                 for i := 1 to 10 do {pack}
  384.                     name[i] := word[i]; {pack}
  385.             end; (*getname*)
  386.  
  387.             procedure typesymbol;
  388.                 var
  389.                     i: integer;
  390.             begin
  391.                 if ch <> 'i' then
  392.                     begin
  393.                         case ch of
  394.                             'a': 
  395.                                 i := 0;
  396.                             'r': 
  397.                                 i := 1;
  398.                             's': 
  399.                                 i := 2;
  400.                             'b': 
  401.                                 i := 3;
  402.                             'c': 
  403.                                 i := 4;
  404.                         end;
  405.                         op := cop[op] + i;
  406.                     end;
  407.             end; (*typesymbol*)
  408.  
  409.         begin
  410.             p := 0;
  411.             q := 0;
  412.             op := 0;
  413.             getname;
  414.             instr[duminst] := name;
  415.             while instr[op] <> name do
  416.                 op := op + 1;
  417.             if op = duminst then
  418.                 errorl(' illegal instruction     ');
  419.  
  420.             case op of  (* get parameters p,q *)
  421.  
  422.       (*equ,neq,geq,grt,leq,les*)
  423.                 17, 18, 19, 20, 21, 22: 
  424.                     begin
  425.                         case ch of
  426.                             'a': 
  427.                                 ; (*p = 0*)
  428.                             'i': 
  429.                                 p := 1;
  430.                             'r': 
  431.                                 p := 2;
  432.                             'b': 
  433.                                 p := 3;
  434.                             's': 
  435.                                 p := 4;
  436.                             'c': 
  437.                                 p := 6;
  438.                             'm': 
  439.                                 begin
  440.                                     p := 5;
  441.                                     read(prd, q)
  442.                                 end
  443.                         end
  444.                     end;
  445.  
  446.       (*lod,str*)
  447.                 0, 2: 
  448.                     begin
  449.                         typesymbol;
  450.                         read(prd, p, q)
  451.                     end;
  452.  
  453. 4  (*lda*)
  454.                 : 
  455.                     read(prd, p, q);
  456.  
  457. 12 (*cup*)
  458.                 : 
  459.                     begin
  460.                         read(prd, p);
  461.                         labelsearch
  462.                     end;
  463.  
  464. 11 (*mst*)
  465.                 : 
  466.                     read(prd, p);
  467.  
  468. 14 (*ret*)
  469.                 : 
  470.                     case ch of
  471.                         'p': 
  472.                             p := 0;
  473.                         'i': 
  474.                             p := 1;
  475.                         'r': 
  476.                             p := 2;
  477.                         'c': 
  478.                             p := 3;
  479.                         'b': 
  480.                             p := 4;
  481.                         'a': 
  482.                             p := 5
  483.                     end;
  484.  
  485.       (*lao,ixa,mov*)
  486.                 5, 16, 55: 
  487.                     read(prd, q);
  488.  
  489.       (*ldo,sro,ind,inc,dec*)
  490.                 1, 3, 9, 10, 57: 
  491.                     begin
  492.                         typesymbol;
  493.                         read(prd, q)
  494.                     end;
  495.  
  496.       (*ujp,fjp,xjp*)
  497.                 23, 24, 25: 
  498.                     labelsearch;
  499.  
  500. 13 (*ent*)
  501.                 : 
  502.                     begin
  503.                         read(prd, p);
  504.                         labelsearch
  505.                     end;
  506.  
  507. 15 (*csp*)
  508.                 : 
  509.                     begin
  510.                         for i := 1 to 9 do
  511.                             read(prd, ch);
  512.                         getname;
  513.                         while name <> sptable[q] do
  514.                             q := q + 1
  515.                     end;
  516.  
  517. 7 (*ldc*)
  518.                 : 
  519.                     begin
  520.                         case ch of  (*get q*)
  521.                             'i': 
  522.                                 begin
  523.                                     p := 1;
  524.                                     read(prd, i);
  525.                                     if abs(i) >= largeint then
  526.                                         begin
  527.                                             op := 8;
  528.                                             store^[icp].vi := i;
  529.                                             q := maxstk;
  530.                                             repeat
  531.                                                 q := q + 1
  532.                                             until store^[q].vi = i;
  533.                                             if q = icp then
  534.                                                 begin
  535.                                                     icp := icp + 1;
  536.                                                     if icp = overi then
  537.                                                         errorl(' integer table overflow  ');
  538.                                                 end
  539.                                         end
  540.                                     else
  541.                                         q := i
  542.                                 end;
  543.  
  544.                             'r': 
  545.                                 begin
  546.                                     op := 8;
  547.                                     p := 2;
  548.                                     read(prd, r);
  549.                                     store^[rcp].vr := r;
  550.                                     q := overi;
  551.                                     repeat
  552.                                         q := q + 1
  553.                                     until store^[q].vr = r;
  554.                                     if q = rcp then
  555.                                         begin
  556.                                             rcp := rcp + 1;
  557.                                             if rcp = overr then
  558.                                                 errorl(' real table overflow     ');
  559.                                         end
  560.                                 end;
  561.  
  562.                             'n': 
  563.                                 ; (*p,q = 0*)
  564.  
  565.                             'b': 
  566.                                 begin
  567.                                     p := 3;
  568.                                     read(prd, q)
  569.                                 end;
  570.  
  571.                             'c': 
  572.                                 begin
  573.                                     p := 6;
  574.                                     repeat
  575.                                         read(prd, ch);
  576.                                     until ch <> ' ';
  577.                                     if ch <> '''' then
  578.                                         errorl(' illegal character       ');
  579.                                     read(prd, ch);
  580.                                     q := ord(ch);
  581.                                     read(prd, ch);
  582.                                     if ch <> '''' then
  583.                                         errorl(' illegal character       ');
  584.                                 end;
  585.                             '(': 
  586.                                 begin
  587.                                     op := 8;
  588.                                     p := 4;
  589.                                     s := [];
  590.                                     read(prd, ch);
  591.                                     while ch <> ')' do
  592.                                         begin
  593.                                             read(prd, s1, ch);
  594.                                             s := s + [s1]
  595.                                         end;
  596.                                     store^[scp].vs := s;
  597.                                     q := overr;
  598.                                     repeat
  599.                                         q := q + 1
  600.                                     until store^[q].vs = s;
  601.                                     if q = scp then
  602.                                         begin
  603.                                             scp := scp + 1;
  604.                                             if scp = overs then
  605.                                                 errorl(' set table overflow      ');
  606.                                         end
  607.                                 end
  608.                         end (*case*)
  609.                     end;
  610.  
  611. 26 (*chk*)
  612.                 : 
  613.                     begin
  614.                         typesymbol;
  615.                         read(prd, lb, ub);
  616.                         if op = 95 then
  617.                             q := lb
  618.                         else
  619.                             begin
  620.                                 store^[bcp - 1].vi := lb;
  621.                                 store^[bcp].vi := ub;
  622.                                 q := overs;
  623.                                 repeat
  624.                                     q := q + 2
  625.                                 until (store^[q - 1].vi = lb) and (store^[q].vi = ub);
  626.                                 if q = bcp then
  627.                                     begin
  628.                                         bcp := bcp + 2;
  629.                                         if bcp = overb then
  630.                                             errorl(' boundary table overflow ');
  631.                                     end
  632.                             end
  633.                     end;
  634.  
  635. 56 (*lca*)
  636.                 : 
  637.                     begin
  638.                         if mcp + 16 >= overm then
  639.                             errorl(' multiple table overflow ');
  640.                         mcp := mcp + 16;
  641.                         q := mcp;
  642.                         for i := 0 to 15 do (*stringlgth*)
  643.                             begin
  644.                                 read(prd, ch);
  645.                                 store^[q + i].vc := ch
  646.                             end;
  647.                     end;
  648.  
  649. 6 (*sto*)
  650.                 : 
  651.                     typesymbol;
  652.  
  653.                 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 58: 
  654.                     ;
  655.  
  656.       (*ord,chr*)
  657.                 59, 60: 
  658.                     goto 1;
  659.  
  660. 61 (*ujc*)
  661.                 : 
  662.                     ; (*must have same length as ujp*)
  663.  
  664.             end; (*case*)
  665.  
  666.       (* store instruction *)
  667.             with code^[pc div 2] do
  668.                 if odd(pc) then
  669.                     begin
  670.                         op2 := op;
  671.                         p2 := p;
  672.                         q2 := q
  673.                     end
  674.                 else
  675.                     begin
  676.                         op1 := op;
  677.                         p1 := p;
  678.                         q1 := q
  679.                     end;
  680.             pc := pc + 1;
  681. 1:
  682.             readln(prd);
  683.         end; (*assemble*)
  684.  
  685.     begin (*load*)
  686.         init;
  687.         generate;
  688.         pc := 0;
  689.         generate;
  690.     end; (*load*)
  691.  
  692. (*------------------------------------------------------------------------*)
  693.  
  694.     procedure pmd;
  695.         var
  696.             s: integer;
  697.             i: integer;
  698.  
  699.         procedure pt;
  700.         begin
  701.             write(s : 6);
  702.             if abs(store^[s].vi) < maxint then
  703.                 write(store^[s].vi)
  704.             else
  705.                 write('too big ');
  706.             s := s - 1;
  707.             i := i + 1;
  708.             if i = 4 then
  709.                 begin
  710.                     writeln(output);
  711.                     i := 0
  712.                 end;
  713.         end; (*pt*)
  714.  
  715.     begin
  716.         write(' pc =', pc - 1 : 5, ' op =', op : 3, '  sp =', sp : 5, '  mp =', mp : 5, '  np =', np : 5);
  717.         writeln;
  718.         writeln('--------------------------------------');
  719.  
  720.         s := sp;
  721.         i := 0;
  722.         while s >= 0 do
  723.             pt;
  724.         s := maxstk;
  725.         while s >= np do
  726.             pt;
  727.     end; (*pmd*)
  728.  
  729.     procedure errori (theString: beta);
  730.     begin
  731.         writeln;
  732.         writeln(theString);
  733.         pmd;
  734.         goto 1
  735.     end;(*errori*)
  736.  
  737.     function base (ld: integer): address;
  738.         var
  739.             ad: address;
  740.     begin
  741.         ad := mp;
  742.         while ld > 0 do
  743.             begin
  744.                 ad := store^[ad + 1].vm;
  745.                 ld := ld - 1
  746.             end;
  747.         base := ad
  748.     end; (*base*)
  749.  
  750.     procedure compare;
  751. (*comparing is only correct if result by comparing integers will be*)
  752.     begin
  753.         i1 := store^[sp].va;
  754.         i2 := store^[sp + 1].va;
  755.         i := 0;
  756.         b := true;
  757.         while b and (i <> q) do
  758.             if store^[i1 + i].vi = store^[i2 + i].vi then
  759.                 i := i + 1
  760.             else
  761.                 b := false
  762.     end; (*compare*)
  763.  
  764.  
  765.     var
  766.         prrOpen: Boolean;
  767.  
  768.     procedure CheckPrr; {Fix to avoid a prr file if we don't need it!}
  769.         var
  770.             newFile: Str255;
  771.     begin
  772.         if prrOpen then
  773.             exit(CheckPrr);
  774.         newFile := 'p4.err';
  775.         newFile := NewFileName('Output file?');
  776.         rewrite(prr, newFile);
  777.     end;
  778.  
  779.  
  780.     procedure callsp;
  781.         var
  782.             line: boolean;
  783.             adptr, adelnt: address;
  784.             i: integer;
  785.  
  786.         procedure readi (var f: text);
  787.             var
  788.                 ad: address;
  789.         begin
  790.             ad := store^[sp - 1].va;
  791.             read(f, store^[ad].vi);
  792.             store^[store^[sp].va].vc := f^;
  793.             sp := sp - 2
  794.         end;(*readi*)
  795.  
  796.         procedure readr (var f: text);
  797.             var
  798.                 ad: address;
  799.         begin
  800.             ad := store^[sp - 1].va;
  801.             read(f, store^[ad].vr);
  802.             store^[store^[sp].va].vc := f^;
  803.             sp := sp - 2
  804.         end;(*readr*)
  805.  
  806.         procedure readc (var f: text);
  807.             var
  808.                 c: char;
  809.                 ad: address;
  810.         begin
  811.             read(f, c);
  812.             ad := store^[sp - 1].va;
  813.             store^[ad].vc := c;
  814.             store^[store^[sp].va].vc := f^;
  815.             store^[store^[sp].va].vi := ord(f^);
  816.             sp := sp - 2
  817.         end;(*readc*)
  818.  
  819.         procedure writestr (var f: text);
  820.             var
  821.                 i, j, k: integer;
  822.                 ad: address;
  823.         begin
  824.             ad := store^[sp - 3].va;
  825.             k := store^[sp - 2].vi;
  826.             j := store^[sp - 1].vi;
  827.      (* j and k are numbers of characters *)
  828.             if k > j then
  829.                 for i := 1 to k - j do
  830.                     write(f, ' ')
  831.             else
  832.                 j := k;
  833.             for i := 0 to j - 1 do
  834.                 write(f, store^[ad + i].vc);
  835.             sp := sp - 4
  836.         end;(*writestr*)
  837.  
  838.         procedure getfile (var f: text);
  839.             var
  840.                 ad: address;
  841.         begin
  842.             ad := store^[sp].va;
  843.             get(f);
  844.             store^[ad].vc := f^;
  845.             sp := sp - 1
  846.         end;(*getfile*)
  847.  
  848.         procedure putfile (var f: text);
  849.             var
  850.                 ad: address;
  851.         begin
  852.             ad := store^[sp].va;
  853.             f^ := store^[ad].vc;
  854.             put(f);
  855.             sp := sp - 1;
  856.         end;(*putfile*)
  857.  
  858.     begin (*callsp*)
  859.         case q of
  860. 0 (*get*)
  861.             : 
  862.                 case store^[sp].va of
  863.                     5: 
  864.                         getfile(input);
  865.                     6: 
  866.                         errori(' get on output file      ');
  867.                     7: 
  868.                         getfile(prd);
  869.                     8: 
  870.                         errori(' get on prr file     ')
  871.                 end;
  872. 1 (*put*)
  873.             : 
  874.                 case store^[sp].va of
  875.                     5: 
  876.                         errori(' put on read file    ');
  877.                     6: 
  878.                         putfile(output);
  879.                     7: 
  880.                         errori(' put on prd file     ');
  881.                     8: 
  882.                         begin
  883.                             CheckPrr; {Fix to avoid a prr file if we don't need it!}
  884.                             putfile(prr)
  885.                         end;
  886.                 end;
  887. 2 (*rst*)
  888.             : 
  889.                 begin
  890.             (*for testphase*)
  891.                     np := store^[sp].va;
  892.                     sp := sp - 1
  893.                 end;
  894. 3 (*rln*)
  895.             : 
  896.                 begin
  897.                     case store^[sp].va of
  898.                         5: 
  899.                             begin
  900.                                 readln(input);
  901.                                 store^[inputadr].vc := input^
  902.                             end;
  903.                         6: 
  904.                             errori(' readln on output file   ');
  905.                         7: 
  906.                             begin
  907.                                 readln(input);
  908.                                 store^[inputadr].vc := input^
  909.                             end;
  910.                         8: 
  911.                             errori(' readln on prr file      ')
  912.                     end;
  913.                     sp := sp - 1
  914.                 end;
  915. 4 (*new*)
  916.             : 
  917.                 begin
  918.                     ad := np - store^[sp].va;
  919.               (*top of stack gives the length in units of storage *)
  920.                     if ad <= ep then
  921.                         errori(' store overflow      ');
  922.                     np := ad;
  923.                     ad := store^[sp - 1].va;
  924.                     store^[ad].va := np;
  925.                     sp := sp - 2
  926.                 end;
  927. 5 (*wln*)
  928.             : 
  929.                 begin
  930.                     case store^[sp].va of
  931.                         5: 
  932.                             errori(' writeln on input file   ');
  933.                         6: 
  934.                             writeln(output);
  935.                         7: 
  936.                             errori(' writeln on prd file     ');
  937.                         8: 
  938.                             begin
  939.                                 CheckPrr; {Fix to avoid a prr file if we don't need it!}
  940.                                 writeln(prr)
  941.                             end;
  942.                     end;
  943.                     sp := sp - 1
  944.                 end;
  945. 6 (*wrs*)
  946.             : 
  947.                 case store^[sp].va of
  948.                     5: 
  949.                         errori(' write on input file     ');
  950.                     6: 
  951.                         writestr(output);
  952.                     7: 
  953.                         errori(' write on prd file       ');
  954.                     8: 
  955.                         begin
  956.                             CheckPrr; {Fix to avoid a prr file if we don't need it!}
  957.                             writestr(prr)
  958.                         end;
  959.                 end;
  960. 7 (*eln*)
  961.             : 
  962.                 begin
  963.                     case store^[sp].va of
  964.                         5: 
  965.                             line := eoln(input);
  966.                         6: 
  967.                             errori(' eoln output file    ');
  968.                         7: 
  969.                             line := eoln(prd);
  970.                         8: 
  971.                             errori(' eoln on prr file    ')
  972.                     end;
  973.                     store^[sp].vb := line
  974.                 end;
  975. 8 (*wri*)
  976.             : 
  977.                 begin
  978.                     case store^[sp].va of
  979.                         5: 
  980.                             errori(' write on input file     ');
  981.                         6: 
  982.                             write(output, store^[sp - 2].vi : store^[sp - 1].vi);
  983.                         7: 
  984.                             errori(' write on prd file       ');
  985.                         8: 
  986.                             begin
  987.                                 CheckPrr; {Fix to avoid a prr file if we don't need it!}
  988.                                 write(prr, store^[sp - 2].vi : store^[sp - 1].vi)
  989.                             end;
  990.                     end;
  991.                     sp := sp - 3
  992.                 end;
  993. 9 (*wrr*)
  994.             : 
  995.                 begin
  996.                     case store^[sp].va of
  997.                         5: 
  998.                             errori(' write on input file     ');
  999.                         6: 
  1000.                             write(output, store^[sp - 2].vr : store^[sp - 1].vi);
  1001.                         7: 
  1002.                             errori(' write on prd file       ');
  1003.                         8: 
  1004.                             begin
  1005.                                 CheckPrr; {Fix to avoid a prr file if we don't need it!}
  1006.                                 write(prr, store^[sp - 2].vr : store^[sp - 1].vi)
  1007.                             end;
  1008.                     end;
  1009.                     sp := sp - 3
  1010.                 end;
  1011. 10(*wrc*)
  1012.             : 
  1013.                 begin
  1014.                     case store^[sp].va of
  1015.                         5: 
  1016.                             errori(' write on input file     ');
  1017.                         6: 
  1018.                             write(output, store^[sp - 2].vc : store^[sp - 1].vi);
  1019.                         7: 
  1020.                             errori(' write on prd file       ');
  1021.                         8: 
  1022.                             begin
  1023.                                 CheckPrr; {Fix to avoid a prr file if we don't need it!}
  1024.                                 write(prr, chr(store^[sp - 2].vi) : store^[sp - 1].vi);
  1025.                             end;
  1026.                     end;
  1027.                     sp := sp - 3
  1028.                 end;
  1029. 11(*rdi*)
  1030.             : 
  1031.                 case store^[sp].va of
  1032.                     5: 
  1033.                         readi(input);
  1034.                     6: 
  1035.                         errori(' read on output file     ');
  1036.                     7: 
  1037.                         readi(prd);
  1038.                     8: 
  1039.                         errori(' read on prr file    ')
  1040.                 end;
  1041. 12(*rdr*)
  1042.             : 
  1043.                 case store^[sp].va of
  1044.                     5: 
  1045.                         readr(input);
  1046.                     6: 
  1047.                         errori(' read on output file     ');
  1048.                     7: 
  1049.                         readr(prd);
  1050.                     8: 
  1051.                         errori(' read on prr file    ')
  1052.                 end;
  1053. 13(*rdc*)
  1054.             : 
  1055.                 case store^[sp].va of
  1056.                     5: 
  1057.                         readc(input);
  1058.                     6: 
  1059.                         errori(' read on output file     ');
  1060.                     7: 
  1061.                         readc(prd);
  1062.                     8: 
  1063.                         errori(' read on prr file    ')
  1064.                 end;
  1065. 14(*sin*)
  1066.             : 
  1067.                 store^[sp].vr := sin(store^[sp].vr);
  1068. 15(*cos*)
  1069.             : 
  1070.                 store^[sp].vr := cos(store^[sp].vr);
  1071. 16(*exp*)
  1072.             : 
  1073.                 store^[sp].vr := exp(store^[sp].vr);
  1074. 17(*log*)
  1075.             : 
  1076.                 store^[sp].vr := ln(store^[sp].vr);
  1077. 18(*sqt*)
  1078.             : 
  1079.                 store^[sp].vr := sqrt(store^[sp].vr);
  1080. 19(*atn*)
  1081.             : 
  1082.                 store^[sp].vr := arctan(store^[sp].vr);
  1083. 20(*sav*)
  1084.             : 
  1085.                 begin
  1086.                     ad := store^[sp].va;
  1087.                     store^[ad].va := np;
  1088.                     sp := sp - 1
  1089.                 end;
  1090.         end;(*case q*)
  1091.     end;(*callsp*)
  1092.  
  1093.     function GetInFile: Str255;
  1094.         var
  1095.             message, count: Integer;
  1096.             theAppFile: AppFile;
  1097.     begin
  1098.         CountAppFiles(message, count);
  1099.         if count > 0 then
  1100.             begin
  1101.                 GetAppFiles(1, theAppFile);
  1102.                 if SetVol(nil, theAppFile.vRefNum) <> noErr then
  1103.                     ; {We ignore errors for now}
  1104.                 GetInFile := theAppFile.fname;
  1105.             end
  1106.         else
  1107.             begin
  1108.                 GetInFile := OldFileName('');
  1109.             end;
  1110.     end;
  1111.  
  1112. {For Stdfile-dialogs:}
  1113.     var
  1114.         oldFile: Str255;
  1115.         theTextRect: Rect;
  1116. begin (* main *)
  1117.     theTextRect := screenBits.bounds;
  1118.     theTextRect.top := theTextRect.top + 40; {For menu bar and window top}
  1119.     InsetRect(theTextRect, 10, 10);
  1120.     SetTextRect(theTextRect);
  1121.     ShowText;
  1122.     Writeln('Welcome to the P4Mac p-code interpreter!');
  1123.     Writeln('This program is based on the Public Domain compiler P4.');
  1124.     Writeln('Quick port for the Mac by Ingemar Ragnemalm - and don''t ask me why.');
  1125.     Writeln('•••');
  1126.  
  1127. {Fix for Think Pascal's stupid 32k limit:}
  1128.     code := codePtr(NewPtr(sizeof(codeType)));
  1129.     if code = nil then
  1130.         begin
  1131.             SysBeep(1);
  1132.             Writeln('Out of memory trying to allocate ', sizeof(codeType) : 1, ' bytes for "code".');
  1133.             Writeln('Click mouse to exit.');
  1134.             while not Button do
  1135.                 ;
  1136.             halt;
  1137.         end;
  1138.     store := storePtr(NewPtr(sizeof(storeType)));
  1139.     if store = nil then
  1140.         begin
  1141.             SysBeep(1);
  1142.             Writeln('Out of memory trying to allocate ', sizeof(storeType) : 1, ' bytes for "store".');
  1143.             Writeln('Click mouse to exit.');
  1144.             while not Button do
  1145.                 ;
  1146.             halt;
  1147.         end;
  1148.  
  1149. {close(prd); {Behövs det?}
  1150.  
  1151.     oldFile := GetInFile;
  1152.     reset(prd, oldFile);
  1153.  
  1154. {newFile := NewFileName('Output file?');}
  1155.  
  1156. {Borde inte rewrite'a prr förrän vi ser att det krävs nåt ut, väl?}
  1157. {rewrite(prr, newFile); {Var förr rewrite(prr)!!!}
  1158.     prrOpen := false; {Not open yet!}
  1159.  
  1160.     load; (* assembles and stores code *)
  1161.   (* writeln(output); for testing *)
  1162.     pc := 0;
  1163.     sp := -1;
  1164.     mp := 0;
  1165.     np := maxstk + 1;
  1166.     ep := 5;
  1167. {store^[inputadr].vc := input^;}
  1168. {store^[prdadr].vc := prd^; {???}
  1169.     interpreting := true;
  1170.  
  1171.     while interpreting do
  1172.         begin
  1173.     (*fetch*)
  1174.             with code^[pc div 2] do
  1175.                 if odd(pc) then
  1176.                     begin
  1177.                         op := op2;
  1178.                         p := p2;
  1179.                         q := q2
  1180.                     end
  1181.                 else
  1182.                     begin
  1183.                         op := op1;
  1184.                         p := p1;
  1185.                         q := q1
  1186.                     end;
  1187.             pc := pc + 1;
  1188.  
  1189.     (*execute*)
  1190.             case op of
  1191.  
  1192.                 105, 106, 107, 108, 109, 0 (*lod*)
  1193.                 : 
  1194.                     begin
  1195.                         ad := base(p) + q;
  1196.                         sp := sp + 1;
  1197.                         store^[sp] := store^[ad]
  1198.                     end;
  1199.  
  1200.                 65, 66, 67, 68, 69, 1 (*ldo*)
  1201.                 : 
  1202.                     begin
  1203.                         sp := sp + 1;
  1204.                         store^[sp] := store^[q]
  1205.                     end;
  1206.  
  1207.                 70, 71, 72, 73, 74, 2 (*str*)
  1208.                 : 
  1209.                     begin
  1210.                         store^[base(p) + q] := store^[sp];
  1211.                         sp := sp - 1
  1212.                     end;
  1213.  
  1214.                 75, 76, 77, 78, 79, 3 (*sro*)
  1215.                 : 
  1216.                     begin
  1217.                         store^[q] := store^[sp];
  1218.                         sp := sp - 1
  1219.                     end;
  1220.  
  1221. 4 (*lda*)
  1222.                 : 
  1223.                     begin
  1224.                         sp := sp + 1;
  1225.                         store^[sp].va := base(p) + q
  1226.                     end;
  1227.  
  1228. 5 (*lao*)
  1229.                 : 
  1230.                     begin
  1231.                         sp := sp + 1;
  1232.                         store^[sp].va := q
  1233.                     end;
  1234.  
  1235.                 80, 81, 82, 83, 84, 6 (*sto*)
  1236.                 : 
  1237.                     begin
  1238.                         store^[store^[sp - 1].va] := store^[sp];
  1239.                         sp := sp - 2;
  1240.                     end;
  1241.  
  1242. 7 (*ldc*)
  1243.                 : 
  1244.                     begin
  1245.                         sp := sp + 1;
  1246.                         if p = 1 then
  1247.                             begin
  1248.                                 store^[sp].vi := q;
  1249.                             end
  1250.                         else if p = 6 then
  1251.                             store^[sp].vc := chr(q)
  1252.                         else if p = 3 then
  1253.                             store^[sp].vb := q = 1
  1254.                         else (* load nil *)
  1255.                             store^[sp].va := maxstr
  1256.                     end;
  1257.  
  1258. 8 (*lci*)
  1259.                 : 
  1260.                     begin
  1261.                         sp := sp + 1;
  1262.                         store^[sp] := store^[q]
  1263.                     end;
  1264.  
  1265.                 85, 86, 87, 88, 89, 9 (*ind*)
  1266.                 : 
  1267.                     begin
  1268.                         ad := store^[sp].va + q;
  1269.               (* q is a number of storage units *)
  1270.                         store^[sp] := store^[ad]
  1271.                     end;
  1272.  
  1273.                 90, 91, 92, 93, 94, 10 (*inc*)
  1274.                 : 
  1275.                     store^[sp].vi := store^[sp].vi + q;
  1276.  
  1277. 11 (*mst*)
  1278.                 : 
  1279.                     begin (*p=level of calling procedure minus level of called}
  1280. {                  procedure + 1;  set dl and sl, increment sp*)
  1281.                (* then length of this element is}
  1282. {              max(intsize,realsize,boolsize,charsize,ptrsize *)
  1283.                         store^[sp + 2].vm := base(p);
  1284.                (* the length of this element is ptrsize *)
  1285.                         store^[sp + 3].vm := mp;
  1286.                (* idem *)
  1287.                         store^[sp + 4].vm := ep;
  1288.                (* idem *)
  1289.                         sp := sp + 5
  1290.                     end;
  1291.  
  1292. 12 (*cup*)
  1293.                 : 
  1294.                     begin (*p=no of locations for parameters, q=entry point*)
  1295.                         mp := sp - (p + 4);
  1296.                         store^[mp + 4].vm := pc;
  1297.                         pc := q
  1298.                     end;
  1299.  
  1300. 13 (*ent*)
  1301.                 : 
  1302.                     if p = 1 then
  1303.                         begin
  1304.                             sp := mp + q; (*q = length of dataseg*)
  1305.                             if sp > np then
  1306.                                 errori(' store overflow      ');
  1307.                         end
  1308.                     else
  1309.                         begin
  1310.                             ep := sp + q;
  1311.                             if ep > np then
  1312.                                 errori(' store overflow      ');
  1313.                         end;
  1314.             (*q = max space required on stack*)
  1315.  
  1316. 14 (*ret*)
  1317.                 : 
  1318.                     begin
  1319.                         case p of
  1320.                             0: 
  1321.                                 sp := mp - 1;
  1322.                             1, 2, 3, 4, 5: 
  1323.                                 sp := mp
  1324.                         end;
  1325.                         pc := store^[mp + 4].vm;
  1326.                         ep := store^[mp + 3].vm;
  1327.                         mp := store^[mp + 2].vm;
  1328.                     end;
  1329.  
  1330. 15 (*csp*)
  1331.                 : 
  1332.                     callsp;
  1333.  
  1334. 16 (*ixa*)
  1335.                 : 
  1336.                     begin
  1337.                         i := store^[sp].vi;
  1338.                         sp := sp - 1;
  1339.                         store^[sp].va := q * i + store^[sp].va;
  1340.                     end;
  1341.  
  1342. 17 (*equ*)
  1343.                 : 
  1344.                     begin
  1345.                         sp := sp - 1;
  1346.                         case p of
  1347.                             1: 
  1348.                                 store^[sp].vb := store^[sp].vi = store^[sp + 1].vi;
  1349.                             0: 
  1350.                                 store^[sp].vb := store^[sp].va = store^[sp + 1].va;
  1351.                             6: 
  1352.                                 store^[sp].vb := store^[sp].vc = store^[sp + 1].vc;
  1353.                             2: 
  1354.                                 store^[sp].vb := store^[sp].vr = store^[sp + 1].vr;
  1355.                             3: 
  1356.                                 store^[sp].vb := store^[sp].vb = store^[sp + 1].vb;
  1357.                             4: 
  1358.                                 store^[sp].vb := store^[sp].vs = store^[sp + 1].vs;
  1359.                             5: 
  1360.                                 begin
  1361.                                     compare;
  1362.                                     store^[sp].vb := b;
  1363.                                 end;
  1364.                         end; (*case p*)
  1365.                     end;
  1366.  
  1367. 18 (*neq*)
  1368.                 : 
  1369.                     begin
  1370.                         sp := sp - 1;
  1371.                         case p of
  1372.                             0: 
  1373.                                 store^[sp].vb := store^[sp].va <> store^[sp + 1].va;
  1374.                             1: 
  1375.                                 store^[sp].vb := store^[sp].vi <> store^[sp + 1].vi;
  1376.                             6: 
  1377.                                 store^[sp].vb := store^[sp].vc <> store^[sp + 1].vc;
  1378.                             2: 
  1379.                                 store^[sp].vb := store^[sp].vr <> store^[sp + 1].vr;
  1380.                             3: 
  1381.                                 store^[sp].vb := store^[sp].vb <> store^[sp + 1].vb;
  1382.                             4: 
  1383.                                 store^[sp].vb := store^[sp].vs <> store^[sp + 1].vs;
  1384.                             5: 
  1385.                                 begin
  1386.                                     compare;
  1387.                                     store^[sp].vb := not b;
  1388.                                 end
  1389.                         end; (*case p*)
  1390.                     end;
  1391.  
  1392. 19 (*geq*)
  1393.                 : 
  1394.                     begin
  1395.                         sp := sp - 1;
  1396.                         case p of
  1397.                             0: 
  1398.                                 errori(' <,<=,>,>= for address   ');
  1399.                             1: 
  1400.                                 store^[sp].vb := store^[sp].vi >= store^[sp + 1].vi;
  1401.                             6: 
  1402.                                 store^[sp].vb := store^[sp].vc >= store^[sp + 1].vc;
  1403.                             2: 
  1404.                                 store^[sp].vb := store^[sp].vr >= store^[sp + 1].vr;
  1405.                             3: 
  1406.                                 store^[sp].vb := store^[sp].vb >= store^[sp + 1].vb;
  1407.                             4: 
  1408.                                 store^[sp].vb := store^[sp].vs >= store^[sp + 1].vs;
  1409.                             5: 
  1410.                                 begin
  1411.                                     compare;
  1412.                                     store^[sp].vb := b or (store^[i1 + i].vi >= store^[i2 + i].vi)
  1413.                                 end
  1414.                         end; (*case p*)
  1415.                     end;
  1416.  
  1417. 20 (*grt*)
  1418.                 : 
  1419.                     begin
  1420.                         sp := sp - 1;
  1421.                         case p of
  1422.                             0: 
  1423.                                 errori(' <,<=,>,>= for address   ');
  1424.                             1: 
  1425.                                 store^[sp].vb := store^[sp].vi > store^[sp + 1].vi;
  1426.                             6: 
  1427.                                 store^[sp].vb := store^[sp].vc > store^[sp + 1].vc;
  1428.                             2: 
  1429.                                 store^[sp].vb := store^[sp].vr > store^[sp + 1].vr;
  1430.                             3: 
  1431.                                 store^[sp].vb := store^[sp].vb > store^[sp + 1].vb;
  1432.                             4: 
  1433.                                 errori(' set inclusion       ');
  1434.                             5: 
  1435.                                 begin
  1436.                                     compare;
  1437.                                     store^[sp].vb := not b and (store^[i1 + i].vi > store^[i2 + i].vi)
  1438.                                 end
  1439.                         end; (*case p*)
  1440.                     end;
  1441.  
  1442. 21 (*leq*)
  1443.                 : 
  1444.                     begin
  1445.                         sp := sp - 1;
  1446.                         case p of
  1447.                             0: 
  1448.                                 errori(' <,<=,>,>= for address   ');
  1449.                             1: 
  1450.                                 store^[sp].vb := store^[sp].vi <= store^[sp + 1].vi;
  1451.                             6: 
  1452.                                 store^[sp].vb := store^[sp].vc <= store^[sp + 1].vc;
  1453.                             2: 
  1454.                                 store^[sp].vb := store^[sp].vr <= store^[sp + 1].vr;
  1455.                             3: 
  1456.                                 store^[sp].vb := store^[sp].vb <= store^[sp + 1].vb;
  1457.                             4: 
  1458.                                 store^[sp].vb := store^[sp].vs <= store^[sp + 1].vs;
  1459.                             5: 
  1460.                                 begin
  1461.                                     compare;
  1462.                                     store^[sp].vb := b or (store^[i1 + i].vi <= store^[i2 + i].vi)
  1463.                                 end;
  1464.                         end; (*case p*)
  1465.                     end;
  1466.  
  1467. 22 (*les*)
  1468.                 : 
  1469.                     begin
  1470.                         sp := sp - 1;
  1471.                         case p of
  1472.                             0: 
  1473.                                 errori(' <,<=,>,>= for address   ');
  1474.                             1: 
  1475.                                 store^[sp].vb := store^[sp].vi < store^[sp + 1].vi;
  1476.                             6: 
  1477.                                 store^[sp].vb := store^[sp].vc < store^[sp + 1].vc;
  1478.                             2: 
  1479.                                 store^[sp].vb := store^[sp].vr < store^[sp + 1].vr;
  1480.                             3: 
  1481.                                 store^[sp].vb := store^[sp].vb < store^[sp + 1].vb;
  1482.                             5: 
  1483.                                 begin
  1484.                                     compare;
  1485.                                     store^[sp].vb := not b and (store^[i1 + i].vi < store^[i2 + i].vi)
  1486.                                 end
  1487.                         end; (*case p*)
  1488.                     end;
  1489.  
  1490. 23 (*ujp*)
  1491.                 : 
  1492.                     pc := q;
  1493.  
  1494. 24 (*fjp*)
  1495.                 : 
  1496.                     begin
  1497.                         if not store^[sp].vb then
  1498.                             pc := q;
  1499.                         sp := sp - 1
  1500.                     end;
  1501.  
  1502. 25 (*xjp*)
  1503.                 : 
  1504.                     begin
  1505.                         pc := store^[sp].vi + q;
  1506.                         sp := sp - 1
  1507.                     end;
  1508.  
  1509. 95 (*chka*)
  1510.                 : 
  1511.                     if (store^[sp].va < np) or (store^[sp].va > (maxstr - q)) then
  1512.                         errori(' bad pointer value       ');
  1513.  
  1514.                 96, 97, 98, 99, 26 (*chk*)
  1515.                 : 
  1516.                     if (store^[sp].vi < store^[q - 1].vi) or (store^[sp].vi > store^[q].vi) then
  1517.                         errori(' value out of range      ');
  1518.  
  1519. 27 (*eof*)
  1520.                 : 
  1521.                     begin
  1522.                         i := store^[sp].vi;
  1523.                         if i = inputadr then
  1524.                             begin
  1525.                                 store^[sp].vb := eof(input);
  1526.                             end
  1527.                         else
  1528.                             errori(' code in error       ')
  1529.                     end;
  1530.  
  1531. 28 (*adi*)
  1532.                 : 
  1533.                     begin
  1534.                         sp := sp - 1;
  1535.                         store^[sp].vi := store^[sp].vi + store^[sp + 1].vi
  1536.                     end;
  1537.  
  1538. 29 (*adr*)
  1539.                 : 
  1540.                     begin
  1541.                         sp := sp - 1;
  1542.                         store^[sp].vr := store^[sp].vr + store^[sp + 1].vr
  1543.                     end;
  1544.  
  1545. 30 (*sbi*)
  1546.                 : 
  1547.                     begin
  1548.                         sp := sp - 1;
  1549.                         store^[sp].vi := store^[sp].vi - store^[sp + 1].vi
  1550.                     end;
  1551.  
  1552. 31 (*sbr*)
  1553.                 : 
  1554.                     begin
  1555.                         sp := sp - 1;
  1556.                         store^[sp].vr := store^[sp].vr - store^[sp + 1].vr
  1557.                     end;
  1558.  
  1559. 32 (*sgs*)
  1560.                 : 
  1561.                     store^[sp].vs := [store^[sp].vi];
  1562.  
  1563. 33 (*flt*)
  1564.                 : 
  1565.                     store^[sp].vr := store^[sp].vi;
  1566.  
  1567. 34 (*flo*)
  1568.                 : 
  1569.                     store^[sp - 1].vr := store^[sp - 1].vi;
  1570.  
  1571. 35 (*trc*)
  1572.                 : 
  1573.                     store^[sp].vi := trunc(store^[sp].vr);
  1574.  
  1575. 36 (*ngi*)
  1576.                 : 
  1577.                     store^[sp].vi := -store^[sp].vi;
  1578.  
  1579. 37 (*ngr*)
  1580.                 : 
  1581.                     store^[sp].vr := -store^[sp].vr;
  1582.  
  1583. 38 (*sqi*)
  1584.                 : 
  1585.                     store^[sp].vi := sqr(store^[sp].vi);
  1586.  
  1587. 39 (*sqr*)
  1588.                 : 
  1589.                     store^[sp].vr := sqr(store^[sp].vr);
  1590.  
  1591. 40 (*abi*)
  1592.                 : 
  1593.                     store^[sp].vi := abs(store^[sp].vi);
  1594.  
  1595. 41 (*abr*)
  1596.                 : 
  1597.                     store^[sp].vr := abs(store^[sp].vr);
  1598.  
  1599. 42 (*not*)
  1600.                 : 
  1601.                     store^[sp].vb := not store^[sp].vb;
  1602.  
  1603. 43 (*and*)
  1604.                 : 
  1605.                     begin
  1606.                         sp := sp - 1;
  1607.                         store^[sp].vb := store^[sp].vb and store^[sp + 1].vb
  1608.                     end;
  1609.  
  1610. 44 (*ior*)
  1611.                 : 
  1612.                     begin
  1613.                         sp := sp - 1;
  1614.                         store^[sp].vb := store^[sp].vb or store^[sp + 1].vb
  1615.                     end;
  1616.  
  1617. 45 (*dif*)
  1618.                 : 
  1619.                     begin
  1620.                         sp := sp - 1;
  1621.                         store^[sp].vs := store^[sp].vs - store^[sp + 1].vs
  1622.                     end;
  1623.  
  1624. 46 (*int*)
  1625.                 : 
  1626.                     begin
  1627.                         sp := sp - 1;
  1628.                         store^[sp].vs := store^[sp].vs * store^[sp + 1].vs
  1629.                     end;
  1630.  
  1631. 47 (*uni*)
  1632.                 : 
  1633.                     begin
  1634.                         sp := sp - 1;
  1635.                         store^[sp].vs := store^[sp].vs + store^[sp + 1].vs
  1636.                     end;
  1637.  
  1638. 48 (*inn*)
  1639.                 : 
  1640.                     begin
  1641.                         sp := sp - 1;
  1642.                         i := store^[sp].vi;
  1643.                         store^[sp].vb := i in store^[sp + 1].vs;
  1644.                     end;
  1645.  
  1646. 49 (*mod*)
  1647.                 : 
  1648.                     begin
  1649.                         sp := sp - 1;
  1650.                         store^[sp].vi := store^[sp].vi mod store^[sp + 1].vi
  1651.                     end;
  1652.  
  1653. 50 (*odd*)
  1654.                 : 
  1655.                     store^[sp].vb := odd(store^[sp].vi);
  1656.  
  1657. 51 (*mpi*)
  1658.                 : 
  1659.                     begin
  1660.                         sp := sp - 1;
  1661.                         store^[sp].vi := store^[sp].vi * store^[sp + 1].vi
  1662.                     end;
  1663.  
  1664. 52 (*mpr*)
  1665.                 : 
  1666.                     begin
  1667.                         sp := sp - 1;
  1668.                         store^[sp].vr := store^[sp].vr * store^[sp + 1].vr
  1669.                     end;
  1670.  
  1671. 53 (*dvi*)
  1672.                 : 
  1673.                     begin
  1674.                         sp := sp - 1;
  1675.                         store^[sp].vi := store^[sp].vi div store^[sp + 1].vi
  1676.                     end;
  1677.  
  1678. 54 (*dvr*)
  1679.                 : 
  1680.                     begin
  1681.                         sp := sp - 1;
  1682.                         store^[sp].vr := store^[sp].vr / store^[sp + 1].vr
  1683.                     end;
  1684.  
  1685. 55 (*mov*)
  1686.                 : 
  1687.                     begin
  1688.                         i1 := store^[sp - 1].va;
  1689.                         i2 := store^[sp].va;
  1690.                         sp := sp - 2;
  1691.                         for i := 0 to q - 1 do
  1692.                             store^[i1 + i] := store^[i2 + i]
  1693.                (* q is a number of storage units *)
  1694.                     end;
  1695.  
  1696. 56 (*lca*)
  1697.                 : 
  1698.                     begin
  1699.                         sp := sp + 1;
  1700.                         store^[sp].va := q;
  1701.                     end;
  1702.  
  1703.                 100, 101, 102, 103, 104, 57 (*dec*)
  1704.                 : 
  1705.                     store^[sp].vi := store^[sp].vi - q;
  1706.  
  1707. 58 (*stp*)
  1708.                 : 
  1709.                     interpreting := false;
  1710.  
  1711. 59 (*ord*)
  1712.                 : (*only used to change the tagfield*)
  1713.                     begin
  1714.                     end;
  1715.  
  1716. 60 (*chr*)
  1717.                 : 
  1718.                     begin
  1719.                     end;
  1720.  
  1721. 61 (*ujc*)
  1722.                 : 
  1723.                     errori(' case - error        ');
  1724.             end
  1725.         end; (*while interpreting*)
  1726.  
  1727. 1:
  1728.  
  1729.  
  1730. {Exit:}
  1731.     Writeln;
  1732.     Writeln('•••');
  1733. {Writeln('Hit return to exit');}
  1734. {readln(oldFile); {read to anything}
  1735.     writeln('Click mouse to exit.');
  1736.     while not Button do
  1737.         ;
  1738. end.